package org.bookie.core.services.impl;

import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.bookie.core.services.IAuthenticationContext;
import org.bookie.model.security.Access;
import org.bookie.model.security.AuthenticationException;

/**
 * Intercepts the invocation of the method which was annotated by {@link org.bookie.web.security.Access}.
 * After retrieving the required {@link org.bookie.web.security.Role}, which is needed to invoke the method,
 * this class checks if the User claims this Role. The method invocation is a joinpoint on the invoked
 * method.
 * 
 * @author drobiazk
 *
 */
public class MethodInvocationInterceptor implements MethodInterceptor {
	
	/**
	 * Injected service to retrieve the User Application State Object.
	 */
	private IAuthenticationContext ctx;
	
	/**
	 * Performs extra treatments before and after the invocation of the method, which was intercepted.
	 * @param invocation invocation of the method
	 */
	public Object invoke(MethodInvocation invocation) throws Throwable {
		Method method = invocation.getMethod();
		Access access = method.getAnnotation(Access.class);
		if(null!=access){
			if(!ctx.isUserInRole(access.role())){
				throw new AuthenticationException(
						"User is is not authenticated or not authorized " +
						"to invoke the method "+method);
			}
		}
		Object ret=invocation.proceed();
		return ret;
	}
	
	/**
	 * Injector
	 * @category injector
	 * @param ctx
	 */
	public void setCtx(IAuthenticationContext ctx) {
		this.ctx = ctx;
	}
}
